package com.hyh.admin.aop;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hyh.ad.common.annotation.Log;
import com.hyh.ad.common.annotation.LoginLog;
import com.hyh.ad.common.core.domain.AjaxResult;
import com.hyh.ad.common.core.domain.entity.SysLogininfor;
import com.hyh.ad.common.core.domain.entity.SysOperLog;
import com.hyh.ad.common.core.domain.model.LoginBody;
import com.hyh.ad.common.utils.SecurityUtils;
import com.hyh.ad.common.utils.ip.IpUtil;
import com.hyh.admin.sys.service.ISysLoginInforService;
import com.hyh.admin.sys.service.ISysOperLogService;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 登录日志记录切面
 *
 * @author hyh
 * @date 2024-06-012
 */
@Aspect
@Component
public class LoginLogAspect {
    @Autowired
    private HttpServletRequest request;

    @Autowired
    private ISysLoginInforService sysLoginInforService;

    @Pointcut("@annotation(com.hyh.ad.common.annotation.LoginLog)")
    public void operationLogPointCut() {
    }

    @AfterReturning(pointcut = "operationLogPointCut()", returning = "returnValue")
    public void afterReturningLogWrite(JoinPoint joinPoint, Object returnValue)  {
        handleLog(joinPoint, null, returnValue);
    }

    @AfterThrowing(pointcut = "operationLogPointCut()", throwing = "e")
    public void afterThrowingLogWrite(JoinPoint joinPoint, Throwable e)  {
        handleLog(joinPoint, e, null);
    }


    private void handleLog(JoinPoint joinPoint, Throwable e, Object returnValue)  {
        // 创建日志对象
        SysLogininfor sysLogininfor = new SysLogininfor();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        LoginLog log = method.getAnnotation(LoginLog.class);
        String username = "";

        Object[] args = joinPoint.getArgs();

        ObjectMapper objectMapper = new ObjectMapper();
        String params = "";
        try {
            params = objectMapper.writeValueAsString(args);
        } catch (JsonProcessingException jsonProcessingException) {
            jsonProcessingException.printStackTrace();
        }

        // 获取User-Agent
        String userAgentString = request.getHeader("User-Agent");
        UserAgent userAgent = UserAgent.parseUserAgentString(userAgentString);

        // 获取操作系统和浏览器信息
        OperatingSystem os = userAgent.getOperatingSystem();
        Browser browser = userAgent.getBrowser();

        // 获取参数里面的用户名
        if (args.length > 0 && args[0] instanceof LoginBody) {
            LoginBody loginBody = (LoginBody) args[0];
            username = loginBody.getUsername();
        } else {
            username = "Unknown";
        }
        String ipAddress = IpUtil.getIpAddr(request);
        sysLogininfor.setUserName(username);
        sysLogininfor.setIpaddr(ipAddress);
        sysLogininfor.setLoginLocation("内网IP");  // 或者通过IP地址来判断内外网
        sysLogininfor.setOs(os.getName());
        sysLogininfor.setBrowser(browser.getName());
        //时间加上8小时
        sysLogininfor.setLoginTime(LocalDateTime.now().plusHours(8));

        // 设置状态
        if (e != null) {
            sysLogininfor.setStatus("1");
            sysLogininfor.setMsg(e.getMessage()); // 设置错误信息
        } else {
            sysLogininfor.setStatus("0");
            if (returnValue != null) {
                String returnValueString = returnValue.toString(); // 假设 returnValue 是包含 {msg=验证码已过期, code=201} 的对象
                String msg = "";
                // 使用正则表达式提取 msg 字段
                Pattern pattern = Pattern.compile("msg=([^,}]*)");
                Matcher matcher = pattern.matcher(returnValueString);
                if (matcher.find()) {
                    msg = matcher.group(1);
                }
                // 设置 sysLogininfor 的 msg 字段
                sysLogininfor.setMsg(msg);
            } else {
                sysLogininfor.setMsg("Operation completed successfully.");
            }
        }
        try {
            sysLoginInforService.insert(sysLogininfor);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}
